'use strict';
const fs = require("fs");
const path = require("path");
const cProcess = require("child_process");
const cwd = process.cwd();
const utf8 = "utf-8";
const tipReg = /\([^\)]*\)\n/g;

// 暂存所有
function gitAddAll(parsedStatus) {
  if (parsedStatus.unStagedChange || parsedStatus.conflicts || parsedStatus.unStagedFile) {
    cProcess.execSync(`git add -A`);
  }
}
// 取消暂存
function gitUnStage(parsedStatus) {
  if (parsedStatus.staged) {
    cProcess.execSync(`git reset HEAD`);
  }
}

// if (parsedStatus.unStagedFile) {
//   console.log("您有新文件未暂存");
//   console.log(parsedStatus.unStagedFile);
//   // parsedStatus.unStagedFile.forEach(item =>
//   //   cProcess.execSync(`del ${path.join(cwd, item.filePath)}`)
//   // );
// }

function parseListToObj(list, keyReg, valueReg, valCallback){
  const ret = {};
  let curList;
  list.forEach(item => {
    keyReg.test(item) && (ret[item] = curList = []);
    valueReg.test(item) && curList.push(valCallback(item));
  });
  return ret;
}

function parseStatus(status){
  const list = status.replace(tipReg, "").split(/\n/);
  const obj = parseListToObj(list, /^[^\t ]+/, /^[\t][^\t ]+/, function (item) {
    const [type, filePath] = item.replace(/\t/g, "").split(/: */);
    return {type: filePath ? type : null, filePath: filePath || type};
  });
  return {
    conflicts: obj[`Unmerged paths:`],
    staged: obj["Changes to be committed:"],
    unStagedChange: obj["Changes not staged for commit:"],
    unStagedFile: obj["Untracked files:"]
  };
}

function gitCommitAll (conf, option = {}, successMessages){
  const {name, dto} = conf;
  const basePath = path.join(cwd, dto.repertoryPath);
  dto.repertoryList.forEach(repertory => {
    const repertoryPath = path.join(basePath, repertory.name);
    try {
      process.chdir(repertoryPath);
      try{cProcess.execSync(`git commit -m "${option.msg || `no commit`}"`, {encoding: utf8});}catch(e){}
      try{
        cProcess.execSync(`git fetch`, {encoding: utf8});
        const merge = cProcess.execSync(`git merge`, {encoding: utf8});
        if (!/CONFLICT/.test(merge)) {
          try{cProcess.execSync(`git push`, {encoding: utf8});}catch(e){}
        } else {
          successMessages.push({type: "err", msg: `代码冲突 ${repertory.name}`});
        }
      }catch(e){}
      process.chdir(cwd);
    } catch (e) {
      console.log(e);
      process.chdir(cwd);
    }
  });
}

function getGitStatus(conf, option = {}){
  const {name, dto} = conf;
  const basePath = path.join(cwd, dto.repertoryPath);
  return dto.repertoryList.map(repertory => {
    let parsedStatus;
    const repertoryPath = path.join(basePath, repertory.name);
    try {
      process.chdir(repertoryPath);
      const status = cProcess.execSync("git status", {encoding: utf8});
      const $parsedStatus = parseStatus(status);
      option.gitAddAll && gitAddAll($parsedStatus);
      option.gitUnStage && gitUnStage($parsedStatus);
      parsedStatus = {
        workspace: name,
        repertory: repertory.name,
        status: $parsedStatus
      };
      process.chdir(cwd);
    } catch (e) {
      console.log(e);
      process.chdir(cwd);
    }
    return parsedStatus;
  }).filter(item => item);
}

module.exports = {
  getGitStatus, gitAddAll, gitUnStage, gitCommitAll
};
